package icasue.reflect.handles.arrays;

import icasue.reflect.handles.object.ObjectOF;
import icasue.reflect.exceptions.HandleException;
import icasue.reflect.handles.HandleSupplier;
import icasue.reflect.handles.OFAble;
import icasue.reflect.handles.exception.ExceptionOF;
import icasue.reflect.handles.predicate.SureOF;

import java.util.function.Function;

/**
 * @Author: Qiao Hang
 * @CreateDate: 2020/12/4 上午10:56
 * @UpdateDate:
 * @Description:
 */
public class AryOF implements OFAble {

    /**
     * create_  (type,len)
     * get_     (ary,idx)
     * set_     (ary,idx,val)
     * copy_    (ary,len)
     * stream_  (ary)
     * asList_  (ary) *notNull
     *
     * All method check pass.
     */

    public static HandleSupplier.FunctionAry<Object> create_ = (clsAndLen) -> {
        try {
            if(!ObjectOF.notEmptyAry_.test(clsAndLen) || clsAndLen.length != 2)
                throw ExceptionOF.handleExcInvocation_.apply("AryOF.create_ : required 2 params.");
            SureOF.isCls_.accept(clsAndLen[0]);
            SureOF.isInt_.accept(clsAndLen[1]);
            return AryO.create.invoke(clsAndLen[0],clsAndLen[1]);
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("AryOF.create_ : occur an error -> " , throwable.getMessage());
        }
    };

    public static HandleSupplier.FunctionAry<Object> get_ = (ary_Idx) -> {
        try {
            if(!ObjectOF.notEmptyAry_.test(ary_Idx) || ary_Idx.length != 2)
                throw ExceptionOF.handleExcInvocation_.apply("AryOF.get_ : required 2 params.");
            SureOF.isAry_.accept(ary_Idx[0]);
            SureOF.isInt_.accept(ary_Idx[1]);
            return AryO.getIdx.invoke(ary_Idx[0],ary_Idx[1]);
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("AryOF.get_ : occur an error -> " , throwable.getMessage());
        }
    };

    public static HandleSupplier.FunctionAry<Object> set_ = (ary_Idx_val) -> {
        try {
            if(!ObjectOF.notEmptyAry_.test(ary_Idx_val) || ary_Idx_val.length != 3)
                throw ExceptionOF.handleExcInvocation_.apply("AryOF.set_ : required 3 params.");
            SureOF.isAry_.accept(ary_Idx_val[0]);
            SureOF.isInt_.accept(ary_Idx_val[1]);
            return AryO.setIdx.invoke(ary_Idx_val[0],ary_Idx_val[1],ary_Idx_val[2]);
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("AryOF.set_ : occur an error -> " , throwable.getMessage());
        }
    };

    public static HandleSupplier.FunctionAry<Object> copy_ = (ary_len) -> {
        try {
            if(!ObjectOF.notEmptyAry_.test(ary_len) || ary_len.length != 2)
                throw ExceptionOF.handleExcInvocation_.apply("AryOF.copy_ : required 2 params.");
            SureOF.isAry_.accept(ary_len[0]);
            SureOF.isInt_.accept(ary_len[1]);
            return AryO.copy.invoke(ary_len[0],ary_len[1]);
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("AryOF.copy_ : occur an error -> " , throwable.getMessage());
        }
    };

    public static Function<Object,Object> stream_ = (ary) -> {
        try {
            SureOF.isAry_.accept(ary);
            return AryO.stream.invoke(ary);
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("AryOF.stream_ : occur an error -> " , throwable.getMessage());
        }
    };

    public static Function<Object,Object> asList_ = (ary) -> {
        try {
            if (ObjectOF.isNull_.test(ary))
                return AryO.asList.invoke();
            SureOF.isAry_.accept(ary);
            return AryO.asList.invoke(ary);
        } catch (HandleException deepError){
            throw deepError;
        } catch (Throwable throwable) {
            throw ExceptionOF.handleExcInvocation_.apply("AryOF.asList_ : occur an error -> " , throwable.getMessage());
        }
    };

}
